package edu.whut.mall.admin.shiro.realm;


import edu.whut.mall.admin.domain.ShiroSysUser;
import edu.whut.mall.admin.enums.SysStatusEnum;
import edu.whut.mall.admin.mapper.UserCustomMapper;
import edu.whut.mall.admin.service.ISysResourcesService;
import edu.whut.mall.admin.service.ISysUserRoleService;
import edu.whut.mall.admin.service.ISysUserService;
import edu.whut.mall.admin.shiro.util.ShiroUtil;
import edu.whut.mall.model.SysResources;
import edu.whut.mall.model.SysRole;
import edu.whut.mall.model.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @program: footbook
 * @description: 认证
 * @author: Wayne
 * @create: 2020-03-17 12:50
 **/
@Slf4j
public class MyRealm extends AuthorizingRealm {

    private ISysUserService sysUserService;

    private ISysUserRoleService sysUserRoleService;

    private ISysResourcesService sysResourcesService;

    private UserCustomMapper userCustomMapper;

    @Autowired
    public void setSysUserService(ISysUserService sysUserService){
        this.sysUserService=sysUserService;
    }

    @Autowired
    public void setSysUserRoleService(ISysUserRoleService sysUserRoleService) {
        this.sysUserRoleService = sysUserRoleService;
    }

    @Autowired
    public void setSysResourcesService(ISysResourcesService sysResourcesService) {
        this.sysResourcesService = sysResourcesService;
    }

    @Autowired
    public void setUserCustomMapper(UserCustomMapper userCustomMapper) {
        this.userCustomMapper = userCustomMapper;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 权限信息对象info,用来存放查出的用户的所有的角色（role）及权限（permission）
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        ShiroSysUser user = (ShiroSysUser)principalCollection.getPrimaryPrincipal();
        //查出改用户对应的所有角色
        List<SysRole> roles = sysUserRoleService.listRolesByUserId(user.getAdminId());
        //查出用户所对应的角色
        List<SysResources> resourcesList = sysResourcesService.listResourcesByUserId(user.getAdminId());
        //添加到授权信息中
        roles.forEach(role -> {
            info.addRole(role.getName());
        });
        if (!CollectionUtils.isEmpty(resourcesList)) {
            Set<String> permissionSet = new HashSet<>();
            for (SysResources resources : resourcesList) {
                if (!StringUtils.isEmpty(resources.getPermission())) {
                    permissionSet.add(resources.getPermission());
                }
            }
            info.setStringPermissions(permissionSet);


        }
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取token，即前端传入的token
        String username = (String) authenticationToken.getPrincipal();
        SysUser sysUser = sysUserService.getUserByUsername(username);
        ShiroSysUser cacheUser = userCustomMapper.getRedisCacheSysUserByUsername(username);
        if (sysUser == null) {
            throw new UnknownAccountException("账号不存在！");
        }

        if (!SysStatusEnum.AVAILABLE.getCode().equals(sysUser.getStatus())) {
            throw new LockedAccountException("帐号已被锁定，禁止登录！");
        }

        return new SimpleAuthenticationInfo(
                cacheUser,
                sysUser.getPassword(),
                getName()
        );

    }
    /**
     * 清除当前用户权限缓存
     * 使用方法：在需要清除用户权限的地方注入 ShiroRealm,
     * 然后调用其 clearCache方法。
     */
    public void clearCache() {
        PrincipalCollection principals = ShiroUtil.getSubject().getPrincipals();
        super.clearCache(principals);
    }
}
